﻿/*  ----------------------------------------------------------------------------
 *  Microsoft Public License (http://www.microsoft.com/opensource/licenses.mspx#Ms-PL)
 *  
 *  ----------------------------------------------------------------------------
 *  DynamicAspect
 *  ----------------------------------------------------------------------------
 *  File:       WeavableObjectTest.cs
 *  Author:     NiceWk (n9walker@hotmail.com)
 *  ----------------------------------------------------------------------------
 */

using Bizall.Dynamic.Aspect;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Dynamic;
using System.Reflection;
using System.Collections.Generic;
using DynamicAspectTester.Mocks;
using System.Linq;
using System.ComponentModel.Composition;

namespace DynamicAspectTester
{
    
    
    /// <summary>
    ///This is a test class for WeavableObjectTest and is intended
    ///to contain all WeavableObjectTest Unit Tests
    ///</summary>
    [TestClass()]
    public class WeavableObjectTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for WeavableObject`1 Constructor
        ///</summary>
        public void WeavableObjectConstructorTestHelper<T>(T source)
            where T : class
        {
            WeavableObject_Accessor<T> target = new WeavableObject_Accessor<T>(source);
            Assert.IsNotNull(target.source);
        }

        [TestMethod()]
        [DeploymentItem("DynamicAspect.dll")]
        public void WeavableObjectConstructorTest()
        {
            WeavableObjectConstructorTestHelper<TargetClass>(new TargetClass());
        }

        /// <summary>
        ///A test for WeavableObject`1 Constructor
        ///</summary>
        public void WeavableObjectConstructorTest1Helper<T>()
            where T : class
        {
            WeavableObject_Accessor<T> target = new WeavableObject_Accessor<T>();
            Assert.IsNotNull(target.source);
        }

        [TestMethod()]
        [DeploymentItem("DynamicAspect.dll")]
        public void WeavableObjectConstructorTest1()
        {
            WeavableObjectConstructorTest1Helper<GenericParameterHelper>();
        }

        /// <summary>
        ///A test for GetProperty
        ///</summary>
        public void GetPropertyTestHelper<T>()
            where T : class
        {
            WeavableObject_Accessor<T> target = new WeavableObject_Accessor<T>(); // TODO: Initialize to an appropriate value
            DynamicMetaObjectBinder binder = new GetPropertyValueBinder("Name");
            PropertyInfo expected = typeof(T).GetProperty("Name");
            PropertyInfo actual;
            actual = target.GetProperty(binder);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        [DeploymentItem("DynamicAspect.dll")]
        public void GetPropertyTest()
        {
            GetPropertyTestHelper<TargetClass>();
        }

        /// <summary>
        ///A test for IsMatchParameters
        ///</summary>
        public void IsMatchParametersTestHelper<T>()
            where T : class
        {
            WeavableObject_Accessor<T> target = new WeavableObject_Accessor<T>();
            //Test void Greeting()
            ParameterInfo[] parameterInfo = typeof(T).GetMethod("Greeting", new Type[] { }).GetParameters();
            object[] args = new object[0];
            bool expected = true;
            bool actual;
            actual = target.IsMatchParameters(parameterInfo, args);
            Assert.AreEqual(expected, actual, "Fail to test Greeting()");

            //Test void Greeting(string)
            {
                parameterInfo = typeof(T).GetMethod("Greeting", new Type[] { typeof(string) }).GetParameters();
                args = new object[] { "Hello" };
                Assert.IsTrue(target.IsMatchParameters(parameterInfo, args), "Fail to test Greeting(string)");
            }

            //Test string Greeting(string, string)
            {
                parameterInfo = typeof(T).GetMethod("Greeting", new Type[] { typeof(string), typeof(string) }).GetParameters();
                args = new object[] { "Hello", "World" };
                Assert.IsTrue(target.IsMatchParameters(parameterInfo, args), "Fail to test Greeting(string, string)");
            }
        }

        [TestMethod()]
        [DeploymentItem("DynamicAspect.dll")]
        public void IsMatchParametersTest()
        {
            IsMatchParametersTestHelper<TargetClass>();
        }

        /// <summary>
        ///A test for ToString
        ///</summary>
        public void ToStringTestHelper<T>()
            where T : class
        {
            WeavableObject_Accessor<T> target = new WeavableObject_Accessor<T>();
            string expected = target.source.ToString();
            string actual;
            actual = target.ToString();
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        [DeploymentItem("DynamicAspect.dll")]
        public void ToStringTest()
        {
            ToStringTestHelper<GenericParameterHelper>();
        }

      
       /// <summary>
        ///A test for Aspects
        ///</summary>
        [TestMethod()]
        public void AspectsTest()
        {  
            var target = new TargetClass().AsDynamic<TargetClass>();
            Assert.IsNotNull(target.Aspects);
            Assert.IsTrue(target.Aspects.Count() > 0);
        }

        [TestMethod()]
        public void SingletonAspectTest()
        {
            WeavableObject<TargetClass> target1 = new TargetClass().AsDynamic<TargetClass>();
            WeavableObject<TargetClass> target2 = new TargetClass().AsDynamic<TargetClass>();

            Assert.AreEqual(target1.Aspects.First(a => true), target2.Aspects.First(a => true));
        }

   
        /// <summary>
        ///A test for ProcessException
        ///</summary>
         [TestMethod()]
        [ExpectedException(typeof(DynamciException))]
        public void ProcessExceptionTest()
        {
           dynamic target = new TargetClass().AsDynamic<TargetClass>();
            target.Greeting(null);
        }


        /// <summary>
        ///A test for TryGetMember
        ///</summary>
         [TestMethod()]
         public void TryGetAnsSetMemberTest()
         {
             TargetClass source = new TargetClass();
             source.Name = "Member";
             dynamic target = source.AsDynamic<TargetClass>();

             Assert.AreSame(source.Name, target.Name);
         }

        /// <summary>
        ///A test for TryInvokeMember
        ///</summary>
           [TestMethod()]
        public void TryInvokeMemberTest()
        {
            TargetClass source = new TargetClass();
            string expected = source.Greeting("Hello,", "World");
            dynamic target = source.AsDynamic<TargetClass>();
            string actual = target.Greeting("Hello,", "World");
            Assert.AreEqual(expected, actual);
        }

  

    }

}